package com.xgr.wonderful;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Handler;
import android.widget.Toast;

import com.umeng.message.PushAgent;
import com.umeng.message.UTrack;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;
import com.xgr.wonderful.utils.Cache;
import com.xgr.wonderful.utils.HttpProxy;
import com.xgr.wonderful.utils.LocalLikeRelationsUtils;
import com.xgr.wonderful.utils.LocationUtils;
import com.xgr.wonderful.utils.LocalUserUtils;
import com.xgr.wonderful.utils.LogUtils;
import com.xgr.wonderful.utils.Sputil;
import com.xgr.wonderful.utils.ToastFactory;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMChatOptions;
import com.easemob.chat.EMMessage;
import com.easemob.chat.OnMessageNotifyListener;
import com.easemob.chat.OnNotificationClickListener;
import com.easemob.chat.TextMessageBody;
import com.google.gson.Gson;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.utils.StorageUtils;
import com.xgr.wonderful.activity.CommentReceivedActivity;
import com.xgr.wonderful.activity.ConversationActivity;
import com.xgr.wonderful.constant.Constant;
import com.xgr.wonderful.constant.HttpGetUrl;
import com.xgr.wonderful.db.DatabaseUtil;
import com.xgr.wonderful.entity.Status;
import com.xgr.wonderful.entity.SuperConversation;
import com.xgr.wonderful.entity.User;
import com.xgr.wonderful.utils.ActivityManagerUtils;
import com.xgr.wonderful.utils.HttpProxy.IHttpRequestListener;

public class MyApplication extends Application {
	private String TAG ="MyApplication" ;
	private static MyApplication myApplication = null;
	
	private Sputil sputil = null;
	
	private PushAgent mPushAgent ;

	public static MyApplication getInstance() {
		return myApplication;
	}
	
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		// 由于Application类本身已经单例，所以直接按以下处理即可。
		myApplication = this;
		sputil = new Sputil(myApplication, Constant.BASIC_PRE_NAME);
		LocationUtils.getInstance().initLocation(this.getApplicationContext());
		initImageLoader();
		// 第三方对话组件的初始化
		initEmSDK();
		
		initUmeng() ;
	}
	
	private void initUmeng() {
		mPushAgent = PushAgent.getInstance(this ) ;
		mPushAgent.setDebugMode(true) ;
//		/**
//		 * 自定义消息处理
//		 * 该Handler是在IntentService中被调用，故
//		 * 1. 如果需启动Activity，需添加Intent.FLAG_ACTIVITY_NEW_TASK
//		 * 2. IntentService里的onHandleIntent方法是并不处于主线程中，因此，如果需调用到主线程，需如下所示;
//		 * 	      或者可以直接启动Service
//		 * */
//		UmengMessageHandler messageHandler = new UmengMessageHandler(){
//
//			@Override
//			public void dealWithCustomMessage(final Context context, final UMessage msg) {
//				new Handler(getMainLooper()).post(new Runnable() {
//					
//					@Override
//					public void run() {
//						ToastFactory.getToast(context, msg.custom+" 1").show();
//						LogUtils.i(TAG, "messageHandler1"+msg.custom);
//					}
//				});
//			}
//			
//		} ;
//		mPushAgent.setMessageHandler(messageHandler) ;
		
		/**
		 * 自定义通知打开动作
		 * 该Handler是在BroadcastReceiver中被调用，故
		 * 如果需启动Activity，需添加Intent.FLAG_ACTIVITY_NEW_TASK
		 * */
		UmengNotificationClickHandler notificationClickHandler= new UmengNotificationClickHandler(){

			@Override
			public void dealWithCustomAction(Context context, UMessage msg) {
				//ToastFactory.getToast(context, msg.custom).show();
				LogUtils.i(TAG, "notificationClickHandler"+msg.custom);
				if (msg.custom.equals("is_ad_show_true")){
					LogUtils.i(TAG, "set add show ture") ;
					sputil.setIsAdShow(true);
				}
				if (msg.custom.equals("is_ad_show_false")){
					LogUtils.i(TAG, "set add show false") ;
					sputil.setIsAdShow(false);
				}
			}
			
		} ;
		mPushAgent.setNotificationClickHandler(notificationClickHandler) ;
	}

	public void addActivity(Activity ac) {
		// 通过全局静态方法返回一个单例对象，然后调用该对象的公有方法
		ActivityManagerUtils.getInstance().addActivity(ac);
	}
	 /**
	  * 只是保存一些 数据 ，不再销毁所有的activity
	  */
	public void exit() {
		LocalUserUtils.getInstance()
				.saveLocalUser(this.getApplicationContext());
		LocalLikeRelationsUtils.getInstance().saveLikeRelations();
		DatabaseUtil.getInstance().closeDB(this.getApplicationContext());
		//后来注释的，然后改变了MainActivity中的backpressed
		//ActivityManagerUtils.getInstance().removeAllActivity();
	}

	public Activity getTopActivity() {
		return ActivityManagerUtils.getInstance().getTopActivity();
	}

	/**
	 * 初始化imageLoader
	 */
	public void initImageLoader() {
		// 图片cache使用的文件
		File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext());
		ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
				getApplicationContext())
				.memoryCache(new LruMemoryCache(5 * 1024 * 1024))
				.memoryCacheSize(10 * 1024 * 1024)
				.discCache(new UnlimitedDiscCache(cacheDir))
				.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
				.build();
		ImageLoader.getInstance().init(config);
	}

	public DisplayImageOptions getOptions(int drawableId) {
		return new DisplayImageOptions.Builder()
		.showImageOnLoading(drawableId)
				.showImageForEmptyUri(drawableId)
				.showImageOnFail(drawableId)
				.resetViewBeforeLoading(true)
				.cacheInMemory(true)
				.cacheOnDisc(true)
				.imageScaleType(ImageScaleType.EXACTLY)
				.bitmapConfig(Bitmap.Config.RGB_565)
				.build();
	}

	// 初始化第三方对话组件
	private void initEmSDK() {
		int pid = android.os.Process.myPid();
		String processName = getAppName(pid);
		// 如果使用到百度地图或者类似启动remote service的第三方库，这个if判断不能少
		if (processName == null || processName.equals("")) {
			// workaround for baidu location sdk
			// 百度定位sdk，定位服务运行在一个单独的进程，每次定位服务启动的时候，都会调用application::onCreate
			// 创建新的进程。
			// 但环信的sdk只需要在主进程中初始化一次。 这个特殊处理是，如果从pid 找不到对应的processInfo
			// processName，
			// 则此application::onCreate 是被service 调用的，直接返回
			return;
		}
		// 初始化环信聊天SDK
		EMChat.getInstance().setDebugMode(true);
		EMChat.getInstance().init(this);

		EMChatOptions options = EMChatManager.getInstance().getChatOptions();
		//
		options.setAcceptInvitationAlways(true);
		// 下面的提醒(是否震动和声音)只是设置的后台 ，不是前台,前台的在Activity的notify中设置
		options.setShowNotificationInBackgroud(true); // 默认为true
		//options.setNotifyBySoundAndVibrate(true);
		options.setNotificationEnable(true) ;
		/**
		 * 从settingUtils中得到设置来修改后台 的options,还有程序启动的时候在application里面设定
		 * 前台的在BaseActivity中的 notification 里面修改 .
		 *  另外当app在后台时，sdk默认以notification的形式通知有新消息，不会走广播
		 */
		if (sputil.isGetAlert()) { // 要有提醒
			LogUtils.i(TAG, "do alert") ;
			options.setNoticeBySound(sputil.isSoundAlert());
		    options.setNoticedByVibrate(sputil.isVibrateAlert());
		} else { // 无声音和 振动的提醒
			options.setNoticeBySound(false);
			options.setNoticedByVibrate(false);
		}

		/**
		 * app在后台时，新消息会通过notification的方式，在手机状态栏提示，
		 * 可以把提示的内容换成自定义的内容(在application的oncreate()里设置)。
		 */
		options.setNotifyText(new OnMessageNotifyListener() {

			@Override
			public int onSetSmallIcon(EMMessage msg) {
				return getApplicationInfo().icon; //==R.drawable.logo
			}

			@Override
			public String onSetNotificationTitle(EMMessage msg) {
				// TODO Auto-generated method stub
				return "微圈";
			}

			@Override
			public String onNewMessageNotify(EMMessage msg) {
				if (msg.getBooleanAttribute(Constant.COMMENT_PUSH_BY_HX, false)== true){
					String fromUsername =msg.getStringAttribute(Constant.COMMENT_PUSH_FROM , "") ;
					return "收到来自"+fromUsername+"的评论";
				}else {
					return "收到了新消息";
				}
			}

			@Override
			public String onLatestMessageNotify(EMMessage msg, int fromUserNum,
					int msgNum) {
				String from = msg.getFrom() ;
				String msgid = msg.getMsgId() ;
				if (msg.getBooleanAttribute(Constant.COMMENT_PUSH_BY_HX, false)== true){
					//如果是评论，要删除 
					EMChatManager.getInstance().getConversation(from).removeMessage(msgid);
					String fromUsername =msg.getStringAttribute(Constant.COMMENT_PUSH_FROM , "") ;
					return "收到来自"+fromUsername+"的"+msgNum+"条新评论";
				}else {
					//设置了收到私聊时的状态
					sputil.setIsNewMsg(true) ;
					return "收到了新消息";
				}
			}
		});
		/**
		 * 用户点击notification消息，sdk会有默认的跳转intent，开发者可以设置自己的跳转intent,如果设置
		 * intent=null,通知栏将什么都没有
		 */
		options.setOnNotificationClickListener(new OnNotificationClickListener() {

			@Override
			public Intent onNotificationClick(EMMessage msg) {
				String from = msg.getFrom() ;
				if (msg.getBooleanAttribute(Constant.COMMENT_PUSH_BY_HX, false)== true){
					//收到的是评论
					Intent intent = new Intent(myApplication ,CommentReceivedActivity.class) ;
					String pushStatusJson = ((TextMessageBody)msg.getBody()).getMessage();
					LogUtils.i(TAG, "status:"+ pushStatusJson) ;
					Status pushStatus  = null;
					try {
						pushStatus = new Gson().fromJson(pushStatusJson, Status.class) ;
						List< Status> commentReceivedStatus = Cache.getCommentRecevicedStatus() ;
						if (commentReceivedStatus!= null && commentReceivedStatus.size()!= 0){
							//已经 存在收到的评论,则要更新一下数据 
							for (Status temp : commentReceivedStatus){
								if (String.valueOf(temp.getId()).equals(String.valueOf(pushStatus.getId()))){
									commentReceivedStatus.remove(temp) ;//这里先删除 再添加 ，可以改变 顺序
								}
							}
						}else {
							commentReceivedStatus = new ArrayList<Status>() ;
						}
					    commentReceivedStatus.add(pushStatus) ;
					    //保存下来
						Cache.putCommentReceivedStatus(new Gson().toJson(commentReceivedStatus)) ;
					} catch (Exception e) {}
					return intent;
				}else {
					//收到的是新的消息，此时应该先查看是否是新的聊天，如果不是，则不用再管，如果是，应该再拉取聊天用户的信息
					DatabaseUtil.getInstance().initConversationDao(myApplication) ;
					if (DatabaseUtil.getInstance().getConversation(Integer.valueOf(from))== null){
						String url = HttpGetUrl.GetUser() + "?id="+ from.toString();
						HttpProxy httpProxy = new HttpProxy() ;
						httpProxy.queryUserByUserID(url, new IHttpRequestListener() {
							
							@Override
							public void OnHttpRequestSuccessful(String result, int errCode) {
								if (errCode == Constant.ERR_HTTP_REQUEST_SUCCESS){
									User remoteUser = null ;
									try {
										remoteUser = new Gson().fromJson(result, User.class);
									} catch (Exception e) {}
									if (remoteUser!= null && remoteUser.getUsername()!= null){
										//下面这句应该可以不加，不清楚
										LogUtils.i(TAG, "new conversation msg push and get user info ok") ;
										SuperConversation superConversation = new SuperConversation(
												remoteUser.getID(), remoteUser.getUsername(),
												remoteUser.getPhoto());
										DatabaseUtil.getInstance().addConversation(
												remoteUser.getID(), superConversation);
									}
								}
							}
							@Override
							public void OnHttpRequestStart() {
							
							}	
							@Override
							public void OnHttpRequestFailure(String info) {
							}
						}) ;
					}
					return new Intent(myApplication, ConversationActivity.class) ;
				}
			}
		});
	}

	private String getAppName(int pID) {
		String processName = null;
		ActivityManager am = (ActivityManager) this
				.getSystemService(ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> l = am.getRunningAppProcesses();
		Iterator<RunningAppProcessInfo> i = l.iterator();
		PackageManager pm = this.getPackageManager();
		while (i.hasNext()) {
			ActivityManager.RunningAppProcessInfo info = (i
					.next());
			try {
				if (info.pid == pID) {
					CharSequence c = pm.getApplicationLabel(pm
							.getApplicationInfo(info.processName,
									PackageManager.GET_META_DATA));
					processName = info.processName;
					return processName;
				}
			} catch (Exception e) {
			}
		}
		return processName;
	}
}
